package br.com.engine.componentes;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import br.com.engine.image.ControleImagem;
import br.com.engine.interfaces.IScript;

public class Animator
{
	Sprite              sprite;
	List<BufferedImage> lstAnimations = new ArrayList<BufferedImage>( );
	List<Sequence>      lstSequencias = new ArrayList<Sequence>( );
	
	Sequence currentSequence;
	long     interval;
	
	public Animator( GameObject obj, int cx, int cy, int initialSrite, int timeInterval )
	{
		this( obj, cx, cy );
		
		setInitialSprite( initialSrite );
		setInteval      ( timeInterval );
	}
	
	public Animator( GameObject obj, int cx, int cy )
	{
		sprite = obj.getComponent( Sprite.class );
		
		BufferedImage[] allImages = ControleImagem.recortarImagem( sprite.getImage( ), cx, cy );
		
		lstAnimations.addAll( Arrays.asList( allImages ) );
		
		obj.addScripts( new Animar( sprite ) );
	}

	public void setInitialSprite( int indice )
	{
		sprite.setImage( lstAnimations.get( indice ) );
		
		currentSequence = new Sequence( "newed", 0, 0 );
		currentSequence.setLock( true );
	}
	
	public void creatAnimation( String nome, int initialFrame, int finalFrame )
	{
		lstSequencias.add( new Sequence( nome, initialFrame, finalFrame ) );
	}
	
	public void setInteval( long interval )
	{
		this.interval = interval;
	}
	
	public void play( String defaultAnimation )
	{
		if( currentSequence.getNome( ).equals( defaultAnimation ) )
			return;
		
		for( Sequence sequence : lstSequencias )
		{
			if( sequence.getNome( ).equals( defaultAnimation ) )
			{
				currentSequence = sequence;
				currentSequence.setLock( false );
			}
		}
	}
	
	public void stop( )
	{
		currentSequence.setLock( true );
	}
	
	private class Animar implements IScript
	{
		private Sprite sprite;
		private long   lastTimeAnimation;
		private long   previous;
		
		public Animar( Sprite sprite )
		{
			this.sprite = sprite;
		}
		
		@Override
		public void update( long time )
		{
			lastTimeAnimation += System.currentTimeMillis( ) - previous;
			
			if( lastTimeAnimation > interval )
			{	
				sprite.setImage( lstAnimations.get( currentSequence.getCurrent( ) ) );
				
				lastTimeAnimation = 0;
			}
			
			previous = System.currentTimeMillis( );
		}
	}
	
	private class Sequence
	{
		private String  nome;
		private int     initialFrame;
		private int     length;
		private int     current;
		private boolean lock;
		
		public Sequence( String nome, int initialFrame, int length )
		{
			setNome        ( nome         );
			setInitialFrame( initialFrame );
			setLength      ( length       );
			setCurrent     ( initialFrame );
		}
		
		public int getLength( )
		{
			return length;
		}
		
		public void setLength( int length ) 
		{
			this.length = length;
		}
		
		public String getNome( )
		{
			return nome;
		}
		
		public void setNome( String nome )
		{
			this.nome = nome;
		}
		
		public void setInitialFrame( int initialFrame ) 
		{
			this.initialFrame = initialFrame;
		}
		
		public int getInitialFrame( )
		{
			return initialFrame;
		}

		public int getCurrent( )
		{
			int ret = current;
			
			adjustCurrent( );
			
			return ret;
		}

		public void setCurrent( int current )
		{
			this.current = current;
		}
		
		public boolean isLock( )
		{
			return lock;
		}

		public void setLock( boolean lock )
		{
			this.lock = lock;
		}
		
		public void adjustCurrent( )
		{
			if( !isLock( ) )
			{
				if( current < getLength( ) )
					current++;
				else if( current == getLength( ) )
					current = getInitialFrame( );
			}
		}
	}
}